package com.ruoyi.project.ins.service.impl;

import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.bean.BeanValidators;
import com.ruoyi.project.ins.domain.InsPromotion;
import com.ruoyi.project.ins.service.IInsPromotionService;
import com.ruoyi.project.mapper.InsPromotionMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.validation.Validator;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class InsPromotionServiceImpl implements IInsPromotionService {

    @Autowired
    private InsPromotionMapper insPromotionMapper;

    @Autowired
    protected Validator validator;

    @Override
    public List<InsPromotion> selectInsPromotionList(InsPromotion insPromotion) {
        return insPromotionMapper.selectInsPromotionList(insPromotion);
    }

    @Override
    public String importAccount(List<InsPromotion> insPromotionList, String operateName) {
        // 一次性取出所有 userId，用于批量查询
        List<String> userIds = insPromotionList.stream()
                .map(InsPromotion::getUserId)
                .filter(Objects::nonNull)
                .distinct()
                .collect(Collectors.toList());

        // 一次查出数据库中已存在的 userId
        List<String> existUserIds = insPromotionMapper.selectExistUserIds(userIds);

        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();

        // 过滤出要插入的新数据
        List<InsPromotion> insertList = new ArrayList<>();
        for (InsPromotion insPromotion : insPromotionList) {
            try {
                if (existUserIds.contains(insPromotion.getUserId())) {
                    failureNum++;
                    failureMsg.append("<br/>").append(failureNum)
                            .append("、用户id ").append(insPromotion.getUserId())
                            .append(" 已存在");
                    continue;
                }

                // 校验数据合法性
                BeanValidators.validateWithException(validator, insPromotion);

                insPromotion.setStatus("0");
                insPromotion.setCreateBy(operateName);
                insertList.add(insPromotion);
            } catch (Exception e) {
                failureNum++;
                String msg = "<br/>" + failureNum + "、用户id " + insPromotion.getUserId() + " 导入失败：";
                failureMsg.append(msg).append(e.getMessage());
                log.error(msg, e);
            }
        }

        // 批量插入，建议每批500或1000条
        final int batchSize = 500;
        for (int i = 0; i < insertList.size(); i += batchSize) {
            int end = Math.min(i + batchSize, insertList.size());
            List<InsPromotion> subList = insertList.subList(i, end);
            insPromotionMapper.batchInsert(subList);
            successNum += subList.size();
        }

        if (failureNum > 0) {
            failureMsg.insert(0, "导入完成！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new ServiceException(failureMsg.toString());
        } else {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }

    @Override
    public int insertInsPromotion(InsPromotion insPromotion) {
        return insPromotionMapper.insertInsPromotion(insPromotion);
    }

    @Override
    public int updateInsPromotion(InsPromotion insPromotion) {
        return insPromotionMapper.updateInsPromotion(insPromotion);
    }

    @Override
    public InsPromotion selectAccountById(Long id) {
        return insPromotionMapper.selectAccountById(id);
    }

    @Override
    public int deleteByIds(Long[] deleteIds) {
        return insPromotionMapper.deleteByIds(deleteIds);
    }

    @Override
    public InsPromotion selectByUserId(String emailAccount) {
        return insPromotionMapper.selectByUserId(emailAccount);
    }

    @Override
    public List<InsPromotion> selectByIds(Long[] ids) {
        return insPromotionMapper.selectByIds(ids);
    }

    @Override
    public List<InsPromotion> selectNoPushedUser() {
        return insPromotionMapper.selectNoPushedUser();
    }

    @Override
    public int updatePromotionUserStatus(String status, String receiveUserid) {
        return insPromotionMapper.updatePromotionUserStatus(status, receiveUserid);
    }

    @Override
    public void batchUpdatePromotions(List<InsPromotion> promotionList) {
        if (CollectionUtils.isEmpty(promotionList)) {
            return;
        }
        int total = promotionList.size();
        for (int i = 0; i < total; i += Constants.MYBATIS_BATCH_MAX_SIZE) {
            int end = Math.min(i + Constants.MYBATIS_BATCH_MAX_SIZE, total);
            List<InsPromotion> subList = promotionList.subList(i, end);
            insPromotionMapper.batchUpdatePromotions(subList);  // 调用MyBatis批量更新
        }
    }

    @Override
    public Map<String, Object> selectSumPromotion(InsPromotion insPromotion) {
        return insPromotionMapper.selectSumPromotion(insPromotion);
    }
}
